package com.boco.blch.dispatcher.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.boco.blch.dispatcher.dao.BigDataDao;
import com.boco.blch.dispatcher.util.AnalyzeXmlInfo;
import com.boco.blch.dispatcher.util.ReportPropertiesUtils;
import com.boco.blch.dispatcher.util.ServiceInfoUtil;
import com.boco.blch.dispatcher.util.ZipCompressor;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import net.sf.json.JSONArray;

@Service
public class HtmlReportServiceImpl implements HtmlReportService {
	private static Logger logger = Logger.getLogger(HtmlReportServiceImpl.class);
	@Autowired
	BigDataDao bigDataDao;

	public Template getTemplate(String name) {
		try {
			@SuppressWarnings("deprecation")
			Configuration cfg = new Configuration();
			cfg.setDirectoryForTemplateLoading(new File(ReportPropertiesUtils.getZipFolder()));
			Template temp = cfg.getTemplate(name);
			return temp;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void print(String name, Map<String, Object> root) {
		try {
			Template temp = this.getTemplate(name);
			temp.process(root, new PrintWriter(System.out));
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void HtmlReport(String taskNo, HttpServletResponse response) {
		List<String> checkgroup = new ArrayList<String>();

		Map<String, Object> root = new HashMap<String, Object>();
		AnalyzeXmlInfo analyzeXmlInfo = new AnalyzeXmlInfo();
		Map<String, String> param = new HashMap<String, String>();
		param.put("taskNo", taskNo);
		// 获取Xml中解析出来的数据
		Map<String, Object> InfoMap = analyzeXmlInfo.XmlInfo(
				"http://localhost:" + ServiceInfoUtil.getPort() + "//BOCO_Baseline_Result", param);
		// 检查信息表中的数据
		Map<String, Object> allInfoMap = (Map<String, Object>) InfoMap.get("allInfoMap");
		String complianceRate = allInfoMap.get("complianceRateString").toString();
		String deviceCount = allInfoMap.get("deviceCountString").toString();
		String totalCount = allInfoMap.get("totalCountString").toString();
		String complianceCount = allInfoMap.get("complianceCountString").toString();
		String uncomlianceCount = allInfoMap.get("uncomlianceCountString").toString();
		root.put("taskno", "123456789");
		root.put("planname", "大数据基线调查");
		root.put("taskcreate", "郭玲");
		root.put("checktotal", totalCount);
		root.put("eqptotal", deviceCount);
		root.put("checkgroup", "三星");
		root.put("tasttime", "2017-11-10");
		root.put("endtime", "2017-11-17");
		root.put("usetime", "40h");
		root.put("compliance", complianceRate);
		root.put("cmpnumber", complianceCount);
		root.put("nocmpnumber", uncomlianceCount);
        //定义一个集合装受检主机Ip
		List<String> ipList = new ArrayList<String>();
		// 定义一个装载合规项详细内容的List
		List<Map<String, Object>> cmpList = new ArrayList<Map<String, Object>>();
		// 定义一个不合规详细内容的List
		List<Map<String, Object>> nocmpList = new ArrayList<Map<String, Object>>();
		// 受检设备一览表数据填充
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		// 定义一个集合装载受检组件
		//遍历InfoMapList（allMapInfo,result(ip(),component()),result(ip(),component())...）
	    List<Map<String, Object>> resultMapList = (List<Map<String, Object>>) InfoMap.get("resultMapList");
	    List<Map<String, Object>> componentMapList = null;
		for (int i = 0; i < resultMapList.size(); i++) {
			Map<String, Object> resultMap = resultMapList.get(i);
            //获取到result-ipInfo
			Map<String, Object> ipInfo =(Map<String, Object>) resultMap.get("ipInfo");

			Map<String, Object> map = new HashMap<String, Object>();
			String iptotalCount = ipInfo.get("iptotalCount").toString();
			String ipuncomplianceCount = ipInfo.get("ipuncomplianceCount").toString();
			String ipcomplianceRate = ipInfo.get("ipcomplianceRate").toString();
			String ipcomplianceCount = ipInfo.get("ipcomplianceCount").toString();
			String ipString = ipInfo.get("ipString").toString();
			//String ipString1= resultSetMap.get("ipString").toString();
			if (!ipList.contains(ipString)){
				ipList.add(ipString);
			}
			map.put("ip", ipString);
			map.put("check", checkgroup.toString().replace("[", "").replace("]", ""));
			map.put("cmp", ipcomplianceCount);
			map.put("nocmp", ipuncomplianceCount);
			map.put("rate", ipcomplianceRate);
			list.add(map);

			componentMapList =(List<Map<String, Object>>) resultMap.get("componentMapList");
			
		}
		//获取到result-Componetmap
		
		List<Map<String, Object>> resultSetMapList = null;
		for(int x = 0;x<componentMapList.size();x++){
			Map<String,Object> Componetmap = componentMapList.get(x);
			resultSetMapList = (List<Map<String, Object>>) Componetmap.get("resultSetMapList");
			//通过component的属性，找出受检组件的名字，放入一个集合
			String checkNameString = (String) Componetmap.get("cmpName");
			if (!checkgroup.contains(checkNameString)) {
				checkgroup.add(checkNameString);
			}
			
		}
		//遍历component下的所有resultSet
		for (int j = 0; j < resultSetMapList.size(); j++) {
			Map<String, Object> resultSetMap = resultSetMapList.get(j);
			String compliance = resultSetMap.get("compliance").toString();
			//判断如果resultSet中compliance为true就为合格项目否则为不合格项目
			if (compliance.contains("true")) {
				cmpList.add(resultSetMap);
			} else {
				nocmpList.add(resultSetMap);
			}
		}
		JSONArray jArray = JSONArray.fromObject(list);
		root.put("json", jArray.toString());
		root.put("checkgroup", checkgroup.toString().replace("[", "").replace("]", ""));
        for (int i = 0;i<ipList.size();i++){
      	String ipString = ipList.get(i);
		  // 按主机分布
		  root.put("ipstatic"+i, ipString);
		  root.put("DeviceIp", ipString);
		  root.put("DeviceIP", ipString);
		  float iptotal = ipList.size();
		  float iprate = (float) 1/iptotal;
		  DecimalFormat decimalFormat = new DecimalFormat(".00");
		  String x = decimalFormat.format(iprate);
		  root.put("iprate"+i,x);
	  }


		// 不合规项目分布
		List<Map<String, Object>> nocmpSpreadInfoList = new ArrayList<Map<String, Object>>();
		//存放不合格项目的名字
		List<String> nocmpSpreadNameList = new ArrayList<String>();
		//遍历不合规项目的集合nocmpList将不合规项目的名字整理进nocmpSpreadNameList
		for (int i = 0; i < nocmpList.size(); i++) {
			//Integer nocmpTotal = nocmpList.size();
			Map<String, Object> resultSetMap = nocmpList.get(i);
			String nocmpName = (String) resultSetMap.get("name");
			if (!nocmpSpreadNameList.contains(nocmpName)) {
				nocmpSpreadNameList.add(nocmpName);
			}
		}
		//统计前十条不合规项目，假设前十条不合规项目的总数为0
		Integer nocmpSpreadTotal = 0;
		List<Map<String, Object>> nocmpPercentList = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < Math.min(10, nocmpSpreadNameList.size()); i++) {
			Map<String, Object> nocmpPercentMap = new HashMap<String, Object>();
			String nocmpSpreadName = nocmpSpreadNameList.get(i);
			Integer nocmpSpreadSize = 0;
			for (int j = 0; j < nocmpList.size(); j++) {
				Map<String, Object> nocmpSpreadMap = nocmpList.get(j);
				String nocmpName = (String) nocmpSpreadMap.get("name");
				if (nocmpSpreadName.contains(nocmpName)) {
					nocmpSpreadSize = nocmpSpreadSize + 1;
				}
			}
			nocmpPercentMap.put("Name", nocmpSpreadName);
			nocmpPercentMap.put("nocmpSpreadSize", nocmpSpreadSize);
			nocmpPercentList.add(nocmpPercentMap);
			nocmpSpreadTotal = nocmpSpreadTotal + nocmpSpreadSize;
		}
		for (int i = 0; i < nocmpPercentList.size(); i++) {
			Map<String, Object> nocmpPercentMap= nocmpPercentList.get(i);
			Integer nocmpSpreadSize = (Integer) nocmpPercentMap.get("nocmpSpreadSize");
			String name = (String) nocmpPercentMap.get("Name");
			float percentF = (float) nocmpSpreadSize / nocmpSpreadTotal * 100;
			DecimalFormat decimalFormat = new DecimalFormat(".00");
			String percent = decimalFormat.format(percentF);
			root.put("percent" + i, percent);
			root.put("data" + i, name);
		}
		root.put("test", "按类型分布（top）10");

		// 详细展示
		// 不合规项目明细的数据nocmpList,合规项目明细的数据cmpList；
		// 将存放不合规项目明细的nocmpList集合转换成JSON数组传到ftl模板中
		JSONArray noCmpDetailArray = JSONArray.fromObject(nocmpList);
		root.put("noCmpDetailArray", noCmpDetailArray.toString().replace("\t", " ").replace("\n", "</br>")
				.replace("\r", " ").replace("'", ""));

		JSONArray CmpDetailArray = JSONArray.fromObject(cmpList);
		root.put("CmpDetailArray",
				CmpDetailArray.toString().replace("\t", " ").replace("\n", " ").replace("\r", " ").replace("'", ""));
		
		File htmlFile = new File(ReportPropertiesUtils.getTemplateFile() + taskNo + ".html");
		fprint(ReportPropertiesUtils.getTemplateFileName(), root, htmlFile);
		// 要被打成压缩包的文件夹
		String f1 = ReportPropertiesUtils.getZipFolder();
		// 压缩后的文件
		File zipFile = null;
		try {
			zipFile = File.createTempFile("reportzip", null);
		} catch (IOException e) {
			e.printStackTrace();
		}
		ZipCompressor.zipMultiFile(f1, zipFile, false);
		
		
        response.setContentType("multipart/form-data");   
        response.setHeader("Content-Disposition", "attachment;fileName=" + taskNo + ".zip");   
		OutputStream os = null;FileInputStream fis = null;
		try{
			os = response.getOutputStream();
			fis = new FileInputStream(zipFile);
			byte[] buffer = new byte[1024];
			int len = 0;
			while((len = fis.read(buffer)) != -1){
				os.write(buffer, 0, len);
			}
		} catch(Exception e){
			logger.error(e);
			e.printStackTrace();
		} finally {
			try {
				if(null != os)
					os.close();
				if(null != fis)
					fis.close();
				zipFile.delete();
				htmlFile.delete();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	
	private File genZipFile(){
		return null;
	}
	
	/**
	 * 
	 * @param name 模板名称
	 * @param outFile 要生产的html的文件名
	 */
	public void fprint(String name, Map<String, Object> root, File outFile) {
		BufferedWriter out = null;
		try {
			if (!outFile.exists()) {
				outFile.createNewFile();
			}
			out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
			Template temp = this.getTemplate(name);
			temp.process(root, out);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
